home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / bitmap.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  8KB  |  295 lines

  1. /* $Id: bitmap.c,v 3.10 1998/07/30 02:39:18 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: bitmap.c,v $
  26.  * Revision 3.10  1998/07/30 02:39:18  brianp
  27.  * feedback/selection modes didn't work
  28.  *
  29.  * Revision 3.9  1998/07/29 04:07:53  brianp
  30.  * feedback was returning wrong values
  31.  *
  32.  * Revision 3.8  1998/05/04 23:54:35  brianp
  33.  * include stdio.h since assert.h needs it on some systems
  34.  *
  35.  * Revision 3.7  1998/03/27 03:30:36  brianp
  36.  * fixed G++ warnings
  37.  *
  38.  * Revision 3.6  1998/03/25 01:24:11  brianp
  39.  * glBitmap in feedback mode returned X,Y offset by bitmap origin (wrong)
  40.  *
  41.  * Revision 3.5  1998/03/05 03:07:56  brianp
  42.  * check for invalid raster pos in gl_direct_bitamp()
  43.  *
  44.  * Revision 3.4  1998/02/27 00:54:29  brianp
  45.  * NULL bitmap image caused assertion- fixed
  46.  *
  47.  * Revision 3.3  1998/02/15 01:32:59  brianp
  48.  * updated driver bitmap function
  49.  *
  50.  * Revision 3.2  1998/02/08 20:23:49  brianp
  51.  * lots of bitmap rendering changes
  52.  *
  53.  * Revision 3.1  1998/02/04 00:33:45  brianp
  54.  * fixed a few cast problems for Amiga StormC compiler
  55.  *
  56.  * Revision 3.0  1998/01/31 20:47:29  brianp
  57.  * initial rev
  58.  *
  59.  */
  60.  
  61.  
  62. #ifdef PC_HEADER
  63. #include "all.h"
  64. #else
  65. #include <assert.h>
  66. #include <stdlib.h>
  67. #include <stdio.h>
  68. #include <string.h>
  69. #include "bitmap.h"
  70. #include "context.h"
  71. #include "feedback.h"
  72. #include "image.h"
  73. #include "macros.h"
  74. #include "pb.h"
  75. #include "pixel.h"
  76. #include "types.h"
  77. #endif
  78.  
  79.  
  80.  
  81. /*
  82.  * Render bitmap data.
  83.  */
  84. static void render_bitmap( GLcontext *ctx, GLint px, GLint py,
  85.                            GLsizei width, GLsizei height,
  86.                            const struct gl_pixelstore_attrib *unpack,
  87.                            const GLubyte *bitmap )
  88. {
  89.    struct pixel_buffer *PB = ctx->PB;
  90.    GLint row, col;
  91.    GLint pz;
  92.  
  93.    if (!bitmap)
  94.       return;
  95.  
  96.    if (ctx->NewState) {
  97.       gl_update_state(ctx);
  98.       PB_INIT( PB, GL_BITMAP );
  99.    }
  100.  
  101.    if (ctx->Visual->RGBAflag) {
  102.       GLint r, g, b, a;
  103.       r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
  104.       g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
  105.       b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
  106.       a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
  107.       PB_SET_COLOR( ctx, PB, r, g, b, a );
  108.    }
  109.    else {
  110.       PB_SET_INDEX( ctx, PB, ctx->Current.RasterIndex );
  111.    }
  112.  
  113.    pz = (GLint) ( ctx->Current.RasterPos[2] * DEPTH_SCALE );
  114.  
  115.    for (row=0; row<height; row++) {
  116.       GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( unpack, bitmap,
  117.                       width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
  118.  
  119.       if (unpack->LsbFirst) {
  120.          /* Lsb first */
  121.          GLubyte bitmask = 1;
  122.          for (col=0; col<width; col++) {
  123.             if (*src & bitmask) {
  124.                PB_WRITE_PIXEL( PB, px+col, py+row, pz );
  125.             }
  126.             bitmask = bitmask << 1;
  127.             if (bitmask==0) {
  128.                src++;
  129.                bitmask = 1;
  130.             }
  131.          }
  132.  
  133.          PB_CHECK_FLUSH( ctx, PB )
  134.  
  135.          /* get ready for next row */
  136.          if (bitmask!=1)
  137.             src++;
  138.       }
  139.       else {
  140.          /* Msb first */
  141.          GLubyte bitmask = 128;
  142.          for (col=0; col<width; col++) {
  143.             if (*src & bitmask) {
  144.                PB_WRITE_PIXEL( PB, px+col, py+row, pz );
  145.             }
  146.             bitmask = bitmask >> 1;
  147.             if (bitmask==0) {
  148.                src++;
  149.                bitmask = 128;
  150.             }
  151.          }
  152.  
  153.          PB_CHECK_FLUSH( ctx, PB )
  154.  
  155.          /* get ready for next row */
  156.          if (bitmask!=128)
  157.             src++;
  158.       }
  159.    }
  160.  
  161.    gl_flush_pb(ctx);
  162. }
  163.  
  164.  
  165.  
  166.  
  167. /*
  168.  * Optimized glBitmap
  169.  */
  170. GLboolean gl_direct_bitmap( GLcontext *ctx, 
  171.                             GLsizei width, GLsizei height,
  172.                             GLfloat xorig, GLfloat yorig,
  173.                             GLfloat xmove, GLfloat ymove,
  174.                             const GLubyte *bitmap )
  175. {
  176.    GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
  177.    GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
  178.    GLboolean completed = GL_FALSE;
  179.  
  180.    if (ctx->Current.RasterPosValid==GL_FALSE) {
  181.       return GL_TRUE;  /* command completed as a no-op */
  182.    }
  183.  
  184.    if (ctx->RenderMode != GL_RENDER)
  185.       return GL_FALSE;
  186.  
  187.    if (ctx->Driver.Bitmap) {
  188.       /* let device driver try to render the bitmap */
  189.       completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
  190.                                          &ctx->Unpack, bitmap );
  191.    }
  192.    if (!completed) {
  193.       /* We can handle an pixel unpacking combo! */
  194.       render_bitmap( ctx, px, py, width, height, &ctx->Unpack, bitmap );
  195.    }
  196.  
  197.    /* update raster position */
  198.    ctx->Current.RasterPos[0] += xmove;
  199.    ctx->Current.RasterPos[1] += ymove;
  200.  
  201.    return GL_TRUE;
  202. }
  203.  
  204.  
  205.  
  206.  
  207. /* Simple unpacking parameters: */
  208. static struct gl_pixelstore_attrib NoUnpack = {
  209.    1,            /* Alignment */
  210.    0,            /* RowLength */
  211.    0,            /* SkipPixels */
  212.    0,            /* SkipRows */
  213.    0,            /* ImageHeight */
  214.    0,            /* SkipImages */
  215.    GL_FALSE,     /* SwapBytes */
  216.    GL_FALSE      /* LsbFirst */
  217. };
  218.  
  219.  
  220.  
  221. /*
  222.  * Execute a glBitmap command:
  223.  *   1. check for errors
  224.  *   2. feedback/render/select
  225.  *   3. advance raster position
  226.  */
  227. void gl_Bitmap( GLcontext* ctx,
  228.                 GLsizei width, GLsizei height,
  229.             GLfloat xorig, GLfloat yorig,
  230.             GLfloat xmove, GLfloat ymove,
  231.                 struct gl_image *bitmap )
  232. {
  233.    if (width<0 || height<0) {
  234.       gl_error( ctx, GL_INVALID_VALUE, "glBitmap" );
  235.       return;
  236.    }
  237.    if (INSIDE_BEGIN_END(ctx)) {
  238.       gl_error( ctx, GL_INVALID_OPERATION, "glBitmap" );
  239.       return;
  240.    }
  241.    if (ctx->Current.RasterPosValid==GL_FALSE) {
  242.       /* do nothing */
  243.       return;
  244.    }
  245.  
  246.    assert(bitmap->Type == GL_BITMAP);
  247.    assert(bitmap->Format == GL_COLOR_INDEX);
  248.    
  249.    if (ctx->RenderMode==GL_RENDER) {
  250.       GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
  251.       GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
  252.       GLboolean completed = GL_FALSE;
  253.       if (ctx->Driver.Bitmap) {
  254.          /* let device driver try to render the bitmap */
  255.          completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
  256.                                             &NoUnpack,
  257.                                             (const GLubyte *) bitmap->Data );
  258.       }
  259.       if (!completed) {
  260.          /* use generic function */
  261.          render_bitmap( ctx, px, py, width, height, &NoUnpack,
  262.                         (const GLubyte *) bitmap->Data );
  263.       }
  264.    }
  265.    else if (ctx->RenderMode==GL_FEEDBACK) {
  266.       GLfloat color[4], texcoord[4], invq;
  267.       color[0] = ctx->Current.RasterColor[0];
  268.       color[1] = ctx->Current.RasterColor[1];
  269.       color[2] = ctx->Current.RasterColor[2];
  270.       color[3] = ctx->Current.RasterColor[3];
  271.       if (ctx->Current.TexCoord[3] == 0.0)
  272.          invq = 1.0F;
  273.       else
  274.          invq = 1.0F / ctx->Current.RasterTexCoord[3];
  275.       texcoord[0] = ctx->Current.RasterTexCoord[0] * invq;
  276.       texcoord[1] = ctx->Current.RasterTexCoord[1] * invq;
  277.       texcoord[2] = ctx->Current.RasterTexCoord[2] * invq;
  278.       texcoord[3] = ctx->Current.RasterTexCoord[3];
  279.       FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
  280.       gl_feedback_vertex( ctx,
  281.                           ctx->Current.RasterPos[0],
  282.               ctx->Current.RasterPos[1],
  283.               ctx->Current.RasterPos[2],
  284.               ctx->Current.RasterPos[3],
  285.               color, ctx->Current.RasterIndex, texcoord );
  286.    }
  287.    else if (ctx->RenderMode==GL_SELECT) {
  288.       /* Bitmaps don't generate selection hits.  See appendix B of 1.1 spec. */
  289.    }
  290.  
  291.    /* update raster position */
  292.    ctx->Current.RasterPos[0] += xmove;
  293.    ctx->Current.RasterPos[1] += ymove;
  294. }
  295.